package io.gitee.kotle.android.view

import android.content.Context
import android.util.AttributeSet
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager.widget.ViewPager
import androidx.viewpager2.widget.ViewPager2
import io.gitee.kotle.android.utils.asOrNull
import io.gitee.kotle.android.utils.createStatusLiveData
import io.gitee.kotle.android.utils.onClick
import io.gitee.kotle.android.utils.success
import io.gitee.kotle.android.widget.BaseRecyclerView

/**
 * 利用recyclerView实现底部导航栏view
 */
open class BottomNavigateView : BaseRecyclerView {
    abstract class BottomNavigateAdapter<Data>(val datas: List<Data>) {

        abstract fun getItemView(parent: ViewGroup, lp: ViewGroup.LayoutParams, viewType: Int): View

        open fun getViewType(position: Int): Int = 0

        abstract fun onBindItemView(itemView: View, data: Data, position: Int, isSelect: Boolean)

        open fun onItemViewClick(itemView: View, data: Data, position: Int) = false
    }

    constructor(context: Context) : super(context)
    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
    constructor(context: Context, attrs: AttributeSet?, defStyle: Int) : super(
        context,
        attrs,
        defStyle
    )

    init {
        itemAnimator = null
        layoutManager =
            object : LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false) {
                override fun canScrollHorizontally(): Boolean {
                    return false
                }

                override fun canScrollVertically(): Boolean {
                    return false
                }
            }
    }

    override fun setLayoutParams(params: ViewGroup.LayoutParams?) {
        super.setLayoutParams(params)
    }

    fun <Data> setBottomNavigateAdapter(adapter: BottomNavigateAdapter<Data>?) {
        if (adapter == null) {
            this.adapter = null
        } else {
            post {
                this.adapter =
                    RcvAdapter(adapter, viewPager2?.currentItem ?: viewPager?.currentItem ?: 0)
            }
        }
    }

    /**
     * 当前界面索引，可以监听设置
     */
    val currentIndexData = createStatusLiveData<Int>()

    /**
     * 设置当前界面位置
     */
    fun setCurrentItem(index: Int, smoothScroll: Boolean = true) {
        viewPager?.setCurrentItem(index, smoothScroll)
        viewPager2?.setCurrentItem(index, smoothScroll)
    }

    private var viewPager: ViewPager? = null
    private var viewPager2: ViewPager2? = null
    private var smoothScroll = false
    fun setupWithViewPager(view: ViewPager, smoothScroll: Boolean = this.smoothScroll) {
        viewPager = view
        this.smoothScroll = smoothScroll
        view.addOnPageChangeListener(object : ViewPager.OnPageChangeListener {
            override fun onPageScrollStateChanged(state: Int) {

            }

            override fun onPageScrolled(
                position: Int,
                positionOffset: Float,
                positionOffsetPixels: Int
            ) {
            }

            override fun onPageSelected(position: Int) {
                adapter.asOrNull<RcvAdapter<*>>()?.notifyPositionChange(position)
            }
        })
        adapter.asOrNull<RcvAdapter<*>>()?.notifyPositionChange(view.currentItem)
    }

    fun setupWithViewPager(view: ViewPager2, smoothScroll: Boolean = this.smoothScroll) {
        viewPager2 = view
        this.smoothScroll = smoothScroll
        view.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
            override fun onPageScrollStateChanged(state: Int) {

            }

            override fun onPageScrolled(
                position: Int,
                positionOffset: Float,
                positionOffsetPixels: Int
            ) {
            }

            override fun onPageSelected(position: Int) {
                adapter.asOrNull<RcvAdapter<*>>()?.notifyPositionChange(position)
            }
        })
        adapter.asOrNull<RcvAdapter<*>>()?.notifyPositionChange(view.currentItem)
    }

    private inner class RcvAdapter<Data>(
        private val adapter: BottomNavigateAdapter<Data>,
        private var select: Int
    ) :
        RecyclerView.Adapter<RcvHolder>() {
        private val datas = mutableListOf<Data>().apply {
            addAll(adapter.datas)
        }
        private val childWidth = width / datas.count()
        override fun getItemViewType(position: Int): Int {
            return adapter.getViewType(position)
        }

        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RcvHolder {
            val lp = ViewGroup.LayoutParams(childWidth, ViewGroup.LayoutParams.MATCH_PARENT)
            val itemView = adapter.getItemView(parent, lp, viewType)
            itemView.layoutParams = lp
            val rcvHolder = RcvHolder(itemView)
            itemView.onClick {
                val newSelectPosition = rcvHolder.layoutPosition
                //onItemViewClick返回true，拦击此次点击
                if (adapter.onItemViewClick(it, datas[newSelectPosition], newSelectPosition)) {
                    return@onClick
                }
                if (newSelectPosition != select) {
                    if (viewPager == null && viewPager2 == null) {
                        notifyPositionChange(newSelectPosition)
                    } else {
                        setCurrentItem(newSelectPosition, smoothScroll)
                    }
                }
            }
            return rcvHolder
        }

        fun notifyPositionChange(newSelectPosition: Int) {
            var datasChange = false
            if (itemCount != adapter.datas.count()) {
                datasChange = true
            } else {
                repeat(itemCount) {
                    if (datas[it] != adapter.datas[it]) {
                        datasChange = true
                        return@repeat
                    }
                }
            }
            if (datasChange) {//数据发生了增删
                post {
                    this@BottomNavigateView.adapter = RcvAdapter(adapter, select).apply {
                        select = newSelectPosition
                    }
                    currentIndexData.success(newSelectPosition)
                }
            } else {
                if (select != newSelectPosition) {
                    val old = select
                    select = newSelectPosition
                    notifyItemChanged(newSelectPosition)
                    notifyItemChanged(old)
                    currentIndexData.success(newSelectPosition)
                }
            }
        }

        override fun getItemCount(): Int = datas.count()

        override fun onBindViewHolder(holder: RcvHolder, position: Int) {
            val isSelect = select == position
            holder.itemView.isSelected = isSelected
            adapter.onBindItemView(holder.itemView, datas[position], position, isSelect)
        }
    }

    private inner class RcvHolder(itemView: View) : RecyclerView.ViewHolder(itemView)
}